package com.yunti.yntk.manager;

import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;
import com.southtslib.common.CallBackType;
import com.southtslib.common.Const;
import com.southtslib.common.DataSourcesEmun;
import com.southtslib.common.TypeEnum;
import com.southtslib.manage.ControlManager;
import com.yunti.yntk.callback.PointPositionCallBack;
import com.yunti.yntk.model.PointPosition;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class TotalStationManager {
    private static TotalStationManager instance = new TotalStationManager();

    private ExecutorService es = Executors.newSingleThreadExecutor();
    private static Context mcontext;
    double[] angle;
    double[] distance;

    int surverTimes = 0;
    public boolean openLASER_POINTER = false;
    public boolean openLASER_PLUMMET = false;
    public double edm = 0;

    public double latchNum;

    private PointPositionCallBack pointPositionCallBack;


    private TotalStationManager() {

    }

    public static TotalStationManager getInstance() {
        if (instance == null) {
            instance = new TotalStationManager();
        }
        return instance;
    }

    public void initStationData() {
        ControlManager.getInstance(mcontext).setConnectStatusCallBack(new ControlManager.IConnectStatusCallBack() {
            @Override
            public void onConnectStatus(boolean b, String s) {
                /*
                 * b : true : false
                 * s : 连接状态相关信息
                 * */
                Toast.makeText(mcontext, "全站仪连接成功", Toast.LENGTH_SHORT).show();
                openLASER_POINTER = false;
                openLASER_PLUMMET = false;
                ControlManager.getInstance(mcontext).controlDevices(TypeEnum.ANGLE, true);
                ControlManager.getInstance(mcontext).controlDevices(TypeEnum.LASER_POINTER, openLASER_POINTER);
                ControlManager.getInstance(mcontext).controlDevices(TypeEnum.LASER_PLUMMET, openLASER_PLUMMET);
                ControlManager.getInstance(mcontext).controlDevicesWithParmas(TypeEnum.EDM, edm);
//                ControlManager.getInstance(mcontext).controlDevices(TypeEnum.LASER_POINTER,true);
            }

            @Override
            public void onDisconnectStatus(boolean b) {
                Toast.makeText(mcontext, "全站仪断开连接", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLeicaCallback(String s) {

            }

        });

        try {
            ControlManager.getInstance(mcontext).setCallbackListener(new ControlManager.IDataRecieveCallback() {
                @Override
                public void onDataCallback(CallBackType type, Bundle bundle) {
                    switch (type) {
                        case angle:
                            angle = bundle.getDoubleArray("angle");
                            if (pointPositionCallBack != null) {
                                if (angle != null && angle.length > 0) {
                                    pointPositionCallBack.newAngle(angle[0]);
                                }
                            }
                            break;
                        case distance:
                            distance = bundle.getDoubleArray("distance");
                            if (pointPositionCallBack != null) {
                                if (distance != null && distance.length > 0) {
                                    pointPositionCallBack.newAngle(distance[0]);
                                }
                            }
                            if (latch != null
                            ) {
                                latch.countDown();
                            }

                            break;
                        case coordinate:
                            double[] coors = bundle.getDoubleArray("coordinate");
                            break;
                        case station:
                            double[] stations = bundle.getDoubleArray("station");
                            break;
                        case power:
                            double[] power = bundle.getDoubleArray("power");
                            break;
                        default:
                            break;
                    }
                }

                @Override
                public void onErrorCallback(final String message) {
                    distance = null;
                    for (int i = 0; i < surverTimes; i++) {
                        latch.countDown();
                    }
                }
            });
        } catch (Exception e) {

        }
    }


    public void init(Context context) {
        mcontext = context;
        ControlManager.getInstance(context).setDataSourcesEmun(DataSourcesEmun.AIDL, Const.INSTRUMENT_552_TYPE);
        initStationData();
        ControlManager.getInstance(context).connectDevices();

    }


    CountDownLatch latch;

    public double[] getDistance() {
        double[] result = new double[10];
        setSurveyTimes();
        latch = new CountDownLatch(surverTimes);
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.ANGLE, true);
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.DISTANCE, true);

        try {
            boolean hasResult = latch.await(4000, TimeUnit.MILLISECONDS);
            result = distance;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return result;
    }

    public PointPosition getPoint() {
        PointPosition point = new PointPosition();
        setSurveyTimes();
        latch = new CountDownLatch(surverTimes);
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.ANGLE, true);
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.DISTANCE, true);

        try {
            latch.await();
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        if (distance != null && !Double.isNaN(distance[0])) {
            point.setTrue(true);
            point.setDistance(distance[0]);
        } else {
            point.setTrue(false);
        }

        if (angle != null && !Double.isNaN(angle[0])) {
            point.setAngle(angle[0]);
        } else {
            point.setTrue(false);
        }
        distance = null;
        angle = null;
        return point;
    }

    public void setSurveyTimes() {
        int surveyMode = ControlManager.getInstance(mcontext).getTSControler().getSurveyMode();
        if (surveyMode == 3) surverTimes = 1;
        else if (surveyMode == 0) surverTimes = ControlManager.getInstance(mcontext).getTSControler().getSurveyTimes();
        else surverTimes = -1;
    }

    public void makeZero() {
        ControlManager.getInstance(mcontext).controlDevicesWithParmas(TypeEnum.AZIMUTH, 0);
    }

    public boolean changeLASER_POINTER() {
        this.openLASER_POINTER = !openLASER_POINTER;
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.EDM, openLASER_POINTER);
        return openLASER_POINTER;
    }

    public void changeLASER_POINTER(boolean open) {
        this.openLASER_POINTER = open;
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.LASER_POINTER, openLASER_POINTER);
    }

    public boolean changeLASER_PLUMMET() {
        this.openLASER_PLUMMET = !openLASER_PLUMMET;
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.LASER_PLUMMET, openLASER_PLUMMET);
        return this.openLASER_PLUMMET;
    }

    public void changeLASER_PLUMMET(boolean open) {
        this.openLASER_PLUMMET = open;
        ControlManager.getInstance(mcontext).controlDevices(TypeEnum.LASER_PLUMMET, openLASER_PLUMMET);
    }

    public void setEdm(double edm) {
        this.edm = edm;
        ControlManager.getInstance(mcontext).controlDevicesWithParmas(TypeEnum.EDM, edm);
    }

    public PointPositionCallBack getPointPositionCallBack() {
        return pointPositionCallBack;
    }

    public void setPointPositionCallBack(PointPositionCallBack pointPositionCallBack) {
        this.pointPositionCallBack = pointPositionCallBack;
    }
}
